import JSEncrypt from 'jsencrypt'
import public_key from '@/config/public_key.js'
// #ifndef MP-WEIXIN
import CryptoJS from 'crypto-js'
// #endif
import { NftWalletApi } from '@/api/modules/NftWallet.js'
import { checkAppApi } from '@/api/checkApp.js'
import { baseImgUrl } from '@/api/app.js'
export const toast = new (class {
  toast(title, duration, position, icon) {
    uni.showToast({
      title: title,
      position: position || 'bottom',
      duration: duration || 1000,
      icon: icon || 'none',
    })
  }
})()

export const loading = new (class {
  showLoading() {
    uni.showLoading()
  }
  hideLoading() {
    uni.hideLoading()
  }
})()
export const Calc = {
  /*
	函数，加法函数，用来得到精确的加法结果
	说明：javascript的加法结果会有误差，在两个浮点数相加的时候会比较明显。这个函数返回较为精确的加法结果。
	参数：arg1：第一个加数；arg2第二个加数；d要保留的小数位数（可以不传此参数，如果不传则不处理小数位数）
	调用：Calc.Add(arg1,arg2,d)
	返回值：两数相加的结果
	*/
  Add: function (arg1, arg2) {
    ;(arg1 = arg1.toString()), (arg2 = arg2.toString())
    var arg1Arr = arg1.split('.'),
      arg2Arr = arg2.split('.'),
      d1 = arg1Arr.length == 2 ? arg1Arr[1] : '',
      d2 = arg2Arr.length == 2 ? arg2Arr[1] : ''
    var maxLen = Math.max(d1.length, d2.length)
    var m = Math.pow(10, maxLen)
    var result = Number(((arg1 * m + arg2 * m) / m).toFixed(maxLen))
    var d = arguments[2]
    return typeof d === 'number' ? Number(result.toFixed(d)) : result
  },
  /*
	函数：减法函数，用来得到精确的减法结果
	说明：函数返回较为精确的减法结果。
	参数：arg1：第一个加数；arg2第二个加数；d要保留的小数位数（可以不传此参数，如果不传则不处理小数位数
	调用：Calc.Sub(arg1,arg2)
	返回值：两数相减的结果
	*/
  Sub: function (arg1, arg2) {
    return Calc.Add(arg1, -Number(arg2), arguments[2])
  },
  /*
	函数：乘法函数，用来得到精确的乘法结果
	说明：函数返回较为精确的乘法结果。
	参数：arg1：第一个乘数；arg2第二个乘数；d要保留的小数位数（可以不传此参数，如果不传则不处理小数位数)
	调用：Calc.Mul(arg1,arg2)
	返回值：两数相乘的结果
	*/
  Mul: function (arg1, arg2) {
    var r1 = arg1.toString(),
      r2 = arg2.toString(),
      m,
      resultVal,
      d = arguments[2]
    m =
      (r1.split('.')[1] ? r1.split('.')[1].length : 0) +
      (r2.split('.')[1] ? r2.split('.')[1].length : 0)
    resultVal =
      (Number(r1.replace('.', '')) * Number(r2.replace('.', ''))) /
      Math.pow(10, m)
    return typeof d !== 'number'
      ? Number(resultVal)
      : Number(resultVal.toFixed(parseInt(d)))
  },
  /*
	函数：除法函数，用来得到精确的除法结果
	说明：函数返回较为精确的除法结果。
	参数：arg1：除数；arg2被除数；d要保留的小数位数（可以不传此参数，如果不传则不处理小数位数)
	调用：Calc.Div(arg1,arg2)
	返回值：arg1除于arg2的结果
	*/
  Div: function (arg1, arg2) {
    var r1 = arg1.toString(),
      r2 = arg2.toString(),
      m,
      resultVal,
      d = arguments[2]
    m =
      (r2.split('.')[1] ? r2.split('.')[1].length : 0) -
      (r1.split('.')[1] ? r1.split('.')[1].length : 0)
    resultVal =
      (Number(r1.replace('.', '')) / Number(r2.replace('.', ''))) *
      Math.pow(10, m)
    return typeof d !== 'number'
      ? Number(resultVal)
      : Number(resultVal.toFixed(parseInt(d)))
  },
}

export const copy = new (class {
  //复制
  copy(data) {
    uni.setClipboardData({
      data: data,
      success: (res) => {
        uni.showToast({
          icon: 'none',
          title: '复制成功',
        })
      },
      fail: (err) => {
        console.log('复制', data, err)
        uni.showToast({
          icon: 'none',
          title: '复制失败',
        })
      },
    })
  }
})()

export const pay = new (class {
  /**
   * 第三方微信支付
   * orderInfo: 订单信息
   * provider: 支付平台 微信 支付宝 苹果内
   */
  // #ifdef APP-PLUS
  wxPayment({ orderInfo }) {
    console.log(orderInfo)
    return new Promise((resolve, reject) => {
      uni.requestPayment({
        provider: 'wxpay',
        orderInfo: orderInfo,
        success: (res) => {
          console.log()
          resolve(res)
        },
        fail: (res) => {
          reject(res)
        },
      })
    })
  }
  // #endif
  // #ifdef MP-WEIXIN
  wxPayment({ orderInfo }) {
    console.log(999, orderInfo)
    return new Promise((resolve, reject) => {
      uni.requestPayment({
        provider: 'wxpay',
        timeStamp: orderInfo.timeStamp,
        nonceStr: orderInfo.nonceStr,
        package: orderInfo.package,
        signType: orderInfo.signType,
        paySign: orderInfo.paySign,
        success: (res) => {
          console.log()
          resolve(res)
        },
        fail: (res) => {
          reject(res)
        },
      })
    })
  }
  // #endif
  /**
   * 第三方支付宝支付
   * orderInfo: 订单信息
   * provider: 支付平台 微信 支付宝 苹果内
   */
  aliPayment({ orderInfo }) {
    return new Promise((resolve, reject) => {
      uni.requestPayment({
        provider: 'alipay',
        orderInfo,
        success: (res) => {
          resolve(res)
        },
        fail: (res) => {
          reject(res)
        },
      })
    })
  }
  /**
   * 第三方苹果应用内支付
   * orderInfo: 订单信息
   * provider: 支付平台 微信 支付宝 苹果内
   */
  ipaPayment({ productId }) {
    console.log('productId', productId)
    return new Promise((resolve, reject) => {
      uni.requestPayment({
        provider: 'appleiap',
        orderInfo: {
          productid: productId,
        },
        success: (res) => {
          // console.log('第三方苹果应用内支付成功', res);
          resolve(res)
        },
        fail: (res) => {
          // console.log('第三方苹果应用内支付失败', res);
          reject(res)
        },
        complete: (res) => {
          // console.log('第三方苹果应用内支付成功或者失败', res);
        },
      })
    })
  }
})()

// 微信小程序检验是否登录，如未登录，前往授权登录界面
export const mustLogin = () => {
  const ifLogin = uni.getStorageSync('token')
  if (!ifLogin) {
    uni.showToast({
      title: '请登录',
      icon: 'none',
    })
    setTimeout(() => {
      uni.navigateTo({
        url: '/pages/login/login/loginWeixin',
      })
    }, 1000)
  }
}

// 微信小程序授权订阅消息弹窗
export const licenseSubscription = () => {
  // #ifdef MP-WEIXIN
  uni.requestSubscribeMessage({
    tmplIds: ['1q0Ik8zcQUmv2HUxyUUeJu7A0OczOOY6zOl192g0nEE'],
    success(res) {
      console.log('订阅成功', res)
    },
    fail(err) {
      console.log('订阅失败', err)
    },
  })
  // #endif
}

export const topx = function (rpx) {
  let num = String(rpx).replace('rpx', '')
  return uni.upx2px(num)
}

export const torpx = function (px) {
  let num = String(px).replace('px', '')
  return num / (uni.upx2px(100) / 100)
}
export const encryptWallet = (privateKey, password) => {
  const encrypt = new JSEncrypt()
  encrypt.setPublicKey(public_key)
  const key = padPassword(password)
  return {
    privateKey: encryptAES(privateKey, key),
    password: encrypt.encrypt(key),
  }
}
export const validatePassword = (password) =>
  /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[A-Za-z\d]{6,16}$/.test(password)

// 判断钱包密码是否输入正确

export const validateWalletPassword = async (password) => {
  const result = await NftWalletApi.getUserWallet()
  if (result.code !== 1) {
    uni.showToast({
      title: '请先创建钱包',
      icon: 'fail',
    })
    return null
  }
  const res = await NftWalletApi.decrypt({
    data: result.data.password,
  })
  if (res.code !== 1) {
    return uni.showToast({ title: res.msg, icon: 'none' })
  }
  if (res.data.trim() == padPassword(password.trim())) {
    return { code: 1 }
  } else {
    return { code: 0 }
  }
}

// 解密私钥
export const decodePrivateKey = async (privateKey) => {
  const result = await NftWalletApi.getUserWallet()
  if (result.code == 1) {
    const res = await NftWalletApi.decrypt({
      data: result.data.password,
    })
    return await decryptAES(privateKey, res.data)
  } else {
    return null
  }
}

export const shortAddress = (
  longAddress,
  length = 6,
  intercept = 4,
  symbol = '...'
) => {
  return longAddress
    ? longAddress.substring(0, length) +
        symbol +
        longAddress.substring(
          longAddress.length - intercept,
          longAddress.length
        )
    : ''
}
export const scanPayment = (data) => {
  const queryString = `id=${data.id}&tjname=${encodeURIComponent(
    data.tjname
  )}&type=${encodeURIComponent(data.type)}`
  const encodedScene = encodeURIComponent(encodeURIComponent(queryString))
  uni.navigateTo({
    url: `/pages/payment/payment?scene=${encodedScene}`,
  })
}
export const thousandsSeparator = (value, fixed = true) => {
  if (!value) return '0'

  let integerPart = ''
  let decimalPart = ''

  if (fixed) {
    const num = parseFloat(value).toFixed(2)
    ;[integerPart, decimalPart] = num.split('.')
  } else {
    ;[integerPart, decimalPart] = value.split('.')
  }

  const formattedInteger = integerPart.replace(/\B(?=(\d{3})+(?!\d))/g, ',')

  return decimalPart !== undefined
    ? `${formattedInteger}.${decimalPart}`
    : formattedInteger
}

export const copyDownloadUrl = () => {
  checkAppApi.getAppInfo().then((res) => {
    if (res.code == 1) {
      uni.setClipboardData({
        data: baseImgUrl + res.data.app_package,
        success() {
          uni.showToast({
            title: '复制下载地址成功',
          })
        },
      })
    } else {
      uni.showToast({
        title: '获取下载地址失败',
        icon: 'none',
      })
    }
  })
}
export const padPassword = (password) => {
  const chars = 'abcdefghijklmnopqrstuvwxyz'
  let paddedPassword = password
  let index = 0

  while (paddedPassword.length < 16) {
    paddedPassword += chars[index % chars.length]
    index++
  }

  return paddedPassword
}
export const encryptAES = (data, key) => {
  const keyHash = CryptoJS.SHA256(key)
  const iv = CryptoJS.lib.WordArray.random(16)
  const options = {
    iv: iv,
    mode: CryptoJS.mode.CBC,
    padding: CryptoJS.pad.Pkcs7,
  }
  const encrypted = CryptoJS.AES.encrypt(data, keyHash, options)
  return iv.concat(encrypted.ciphertext).toString(CryptoJS.enc.Base64)
}
export const decryptAES = (ciphertextBase64, key) => {
  const keyHash = CryptoJS.SHA256(key)
  const rawData = CryptoJS.enc.Base64.parse(ciphertextBase64)
  const iv = CryptoJS.lib.WordArray.create(rawData.words.slice(0, 4))
  const ciphertext = CryptoJS.lib.WordArray.create(rawData.words.slice(4))
  const options = {
    iv: iv,
    mode: CryptoJS.mode.CBC,
    padding: CryptoJS.pad.Pkcs7,
  }
  const decrypted = CryptoJS.AES.decrypt(
    { ciphertext: ciphertext },
    keyHash,
    options
  )
  return decrypted.toString(CryptoJS.enc.Utf8)
}
